﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Utility;
using File = Utility.File;
using Message = Utility.Message;
using System.Configuration;

namespace _411Client.Connect
{
    public class Connect
    {
        /// <summary>
        /// 用户信息
        /// </summary>
        public User Me { get; set; }
        /// <summary>
        /// 用户聊天对象的信息
        /// </summary>
        public User MyFriend { get; set; }
        /// <summary>
        /// 传输给对方的文件地址
        /// </summary>
        public string Filepath { get; set; }

        private Socket _clientSocket;
        private Socket _fileServerSocket;
        private Socket _fileClientSocket;
        private  string _ip;
        private int _port;
        private readonly String _serverIp = ConfigurationManager.AppSettings["ServerIp"];
        private readonly String _MyserverIp = new System.Net.IPAddress(Dns.GetHostByName(Dns.GetHostName()).AddressList[0].Address).ToString();
        private readonly int _serverPort = int.Parse(ConfigurationManager.AppSettings["ServerPort"]);
        /// <summary>
        /// 判断是否有文件请求信息
        /// </summary>
        public bool Filerequest { get; set; }

        /// <summary>
        /// 与服务器连接并获得一个随机聊天对象
        /// </summary>
        public int Connected(string name)
        {
            try
            {
                Filerequest = false;
                IPEndPoint server = new IPEndPoint(IPAddress.Parse(_serverIp), _serverPort); //定义要连接的服务器端点
                _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 构造一个socket
                _clientSocket.Connect(server); // 与服务器连接
                byte[] recvBytes = new byte[1024];
                int bytes = _clientSocket.Receive(recvBytes, recvBytes.Length, 0);
                int id = Int32.Parse(Encoding.Unicode.GetString(recvBytes, 0, bytes));
                _clientSocket.Send(Encoding.Unicode.GetBytes(name));
                Comunicate cate = new Comunicate(_clientSocket, this);
                Thread td = new Thread(cate.Run) {IsBackground = true};
                td.Start();
                return id;
            }
            catch
            {
                return 0;//返回值为0表示连接失败，否则为用户ID
            }
        }

        /// <summary>
        /// 与服务器断开连接
        /// </summary>
        public void Disconnected()
        {
            try
            {
                MyMessage message = new MyMessage
                                        {
                                            MessageType = MessageType.MESSAGE_CLOSE,
                                            Sender = Me,
                                            Accepter = MyFriend
                                        };
                _clientSocket.Send(Serialize.DoSerialize(message));
                if (_clientSocket != null)
                    _clientSocket.Close();
                if (_fileClientSocket.Connected)
                {
                    Filerequest = false;
                    Program.Win.CancelFile();
                    DiconnectFileClientSocket();
                }
                if(_fileServerSocket.Connected)
                {
                     DiconnectFileServerSocket();
                }
               
            }
            catch
            {
            }
        }

        /// <summary>
        /// 发送一条消息
        /// </summary>
        public bool SendMessage(Message msg)
        {
            MyMessage message = new MyMessage();
            message.Mymessage = msg;
            message.MessageType = MessageType.MESSAGE_MESS;
            message.Sender = Me;
            message.Accepter = MyFriend;
            _clientSocket.Send(Serialize.DoSerialize(message));
            return true;
        }

        /// <summary>
        /// 发送一张图片
        /// </summary>
        public bool SendImage(string imagePath)
        {
            MyMessage message = new MyMessage();
            message.MessageType = MessageType.MESSAGE_IMG;
            FileStream file = System.IO.File.OpenRead(imagePath);
            Images img = new Images();
            img.FileContent = new byte[file.Length];
            file.Read(img.FileContent,0,(int)file.Length);
            img.Extension = imagePath.Substring(imagePath.LastIndexOf('.'));
            message.Myimage = img;
            message.Sender = Me;
            message.Accepter = MyFriend;
            _clientSocket.Send(Serialize.DoSerialize(message));
            return true;
        }

        /// <summary>
        /// 发送文件请求
        /// </summary>
        public bool SendFileRequest(string filePath)
        {
            Filepath = filePath;
            MyMessage message = new MyMessage
                                    {
                                        MessageType = MessageType.MESSAGE_FILE,
                                        Sender = Me,
                                        Accepter = MyFriend,
                                        Name = filePath,
                                        Ip = _MyserverIp,
                                        Port = 8090//TODO 常量？配置文件？
                                    };
            _fileServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress ip = IPAddress.Parse(_MyserverIp); ;
            IPEndPoint serverInfo = new IPEndPoint(ip, 8090);
            _fileServerSocket.Bind(serverInfo);//将SOCKET接口和IP端口绑定
            _fileServerSocket.Listen(5);//开始监听，并且挂起数为10
            _clientSocket.Send(Serialize.DoSerialize(message));
            Thread thread = new Thread(NewConnect) {IsBackground = true};
            thread.Start();
            return true;
        }

        private void NewConnect()
        {
            try
            {
                _fileClientSocket = _fileServerSocket.Accept();
            }
            catch (Exception)
            {
               if(_fileClientSocket!=null)
                   _fileClientSocket.Close();
            }
           
        }

       /// <summary>
       /// 接收文件连接
       /// </summary>
        public void ReceiveFileConnect(string ip, int port, String name)
       {
           _ip = ip;
           _port = port;
           Filerequest = true;
           Program.Win.ReceiveFileRequest(name);

       }

        /// <summary>
        /// 发送文件
        /// </summary>
        public void SendFile(string filePath)
        {
            //以二进制格式读取文件内容
            FileStream fsr = new FileStream(filePath, FileMode.Open);
            File file = new File();
            file.Name = Filepath.Substring(0, Filepath.LastIndexOf('.'));
            file.Extension = Filepath.Substring(Filepath.LastIndexOf('.'));
            file.FileContent = new byte[fsr.Length];
            fsr.Read(file.FileContent, 0, file.FileContent.Length);
            _fileClientSocket.Send(Serialize.DoSerialize(file));   //FileClientSocket未释放
            fsr.Close();
            DiconnectFileServerSocket();
        }

        /// <summary>
        /// 同意接受文件
        /// </summary>
        public bool PermitFile()
        {
            try
            {
                IPEndPoint server = new IPEndPoint(IPAddress.Parse(_ip), _port); //定义要连接的服务器端点
                _fileClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 构造一个socket
                _fileClientSocket.Connect(server); // 与服务器连接
            }
            catch
            {
                _fileClientSocket.Close();
            }
            MyMessage message = new MyMessage();
            message.MessageType = MessageType.MESSAGE_OK;
            message.Sender = Me;
            message.Accepter = MyFriend;
            _clientSocket.Send(Serialize.DoSerialize(message));
            Thread thread = new Thread(SaveFile) {IsBackground = true};
            thread.Start();
            return true;
        }

        /// <summary>
        /// 断开文件服务器
        /// </summary>
        public void DiconnectFileServerSocket()
        {
            _fileServerSocket.Close();
        }
        /// <summary>
        /// 断开客户端套接字
        /// </summary>
        public void DiconnectFileClientSocket()
        {
            _fileClientSocket.Close();
        }

        private void SaveFile()
        {
            byte[] recvFile = new byte[10240000];
            _fileClientSocket.Receive(recvFile);
            _fileClientSocket.Close();
            Program.Win.ReceiveFile((File) Serialize.Userialize(recvFile));
        }

        /// <summary>
        /// 拒绝接受文件
        /// </summary>
        public bool RejectFile()
        {
            MyMessage message = new MyMessage
                                    {
                                        MessageType = MessageType.MESSAGE_REJECT,
                                        Sender = Me,
                                        Accepter = MyFriend
                                    };
            _clientSocket.Send(Serialize.DoSerialize(message));
            return true;
        }

        /// <summary>
        /// 取消传送文件
        /// </summary>
        public bool CancelFile()
        {
            MyMessage message = new MyMessage
                                    {
                                        MessageType = MessageType.MESSAGE_CANCEL,
                                        Sender = Me,
                                        Accepter = MyFriend
                                    };
            _clientSocket.Send(Serialize.DoSerialize(message));
            DiconnectFileServerSocket();
            return true;
        }
    }
}
